package org.example.spring.WebSocket;


import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import jakarta.websocket.*;
import jakarta.websocket.server.PathParam;
import jakarta.websocket.server.ServerEndpoint;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.PathVariable;


import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

@ServerEndpoint("/chatWebSocket/{account}")       //接口名：chatWebSocket
@Component
@Slf4j
public class WebSocketServer {

    /**
     *  [关于@OnOpen、@OnMessage、@OnClose、@OnError 中 Session session 的用意]
     *
     *  Session session: 主要用于代表一个单独的 WebSocket 连接会话.每当一个 WebSocket 客户端与服务器端点建立连接时，都会创建一个新的 Session 实例
     *      标识连接：每个 Session 对象都有一个唯一的 ID，可以用来识别和跟踪每个单独的连接。   ——>     可以使用 session.getId() 方法来获取这个 ID.对于日志记录、跟踪用户会话等方面非常有用。
     *      管理连接：可以通过 Session 对象来管理对应的 WebSocket 连接，例如发送消息给客户端、关闭连接等    ——>     session.getBasicRemote().sendText(message) 同步地发送文本消息，
     *                                                                                                 或者使用 session.getAsyncRemote().sendText(message) 异步地发送.可以调用 session.close() 来关闭 WebSocket 连接。
     *      获取连接信息：Session 对象提供了方法来获取连接的详细信息，比如连接的 URI、用户属性等。    ——>     可以使用 session.getRequestURI() 获取请求的 URI
     * **/
    private static Map<String,Session>map=new HashMap<>();
    private static Integer size=0;

    //建立连接时
    @OnOpen
    public void onOpen(@PathParam("account") String account, Session session){
        map.put(account, session);
        size++;
        log.info("用户{}已建立连接,用户名为{}",session.getId(),account);
        log.info(String.valueOf(map.get(account)),account);
    }

    @OnClose
    public void  onClose(Session session,@PathParam("account") String account){
        log.info("用户{}已关闭连接,用户名为{}",session.getId(),account);
//        map.remove(account);
    }
    //链接出错时
    @OnError
    public void onError(Session session,Throwable throwable){
        //错误提示
        log.error("出错原因" + throwable.getMessage());
        //抛出异常
        throwable.printStackTrace();
    }

    @OnMessage
    public void OnMessage(String message,Session session,@PathParam("account") String account) throws IOException {
        log.info("会话id"+ session.getId() +"对应的会话用户：" + account + "的消息:" + message);
        JSONObject jsonObject = JSON.parseObject(message);
        ArrayList<String> toAccounts = jsonObject.getObject("toAccounts", ArrayList.class);
        String value = jsonObject.getString("value");
        Integer type = jsonObject.getInteger("type");
        Integer otherId = jsonObject.getInteger("otherId");
        if (type==2){
            for (String toAccount:toAccounts){
                if (map.get(toAccount)!=null){
                    sendToOne(toAccount,value,account,type,otherId);
                }
            }
        }else {
            //发送给自己
            sendMy(account, value, type, otherId);
            //发送给对方
            for (String toAccount : toAccounts) {
                if (map.get(toAccount) != null) {
                    sendToOne(toAccount, value, account, type, otherId);
                }
            }
        }
    }

    //私聊
    public void sendMy(String account,String message,Integer type,Integer otherId) throws IOException {
        Session client=map.get(account);
        Map<String, Object> sendMap=new HashMap<>();
        sendMap.put("account",account);
        sendMap.put("msg",message);
        sendMap.put("type",type);
        sendMap.put("otherId",otherId);
        client.getBasicRemote().sendText(JSON.toJSONString(sendMap));

    }
    public void sendToOne(String toAccount,String message,String account,Integer type,Integer otherId) throws IOException {
        Session client=map.get(toAccount);
        log.info(toAccount,message);
        Map<String,Object> sendMap=new HashMap<>();
        sendMap.put("account",account);
        sendMap.put("msg",message);
        sendMap.put("type",type);
        sendMap.put("otherId",otherId);
        client.getBasicRemote().sendText(JSON.toJSONString(sendMap));

    }

}
